package com.hoperun.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;

import com.hoperun.bean.AdminOrganizations;
import com.hoperun.dao.AdminOrganizationsDAO;
import com.hoperun.framework.ex.XHZException;
import com.hoperun.framework.ibatis.page.BootGrid;
import com.hoperun.framework.ibatis.page.BootGridPage;
import com.hoperun.framework.query.Criteria;
import com.hoperun.service.IAdminOrganizationsSV;
import com.hoperun.utils.Constant;
import com.hoperun.utils.ErrorCode;
import com.hoperun.utils.Constant.RecordState;

@Service("adminOrganizationsSV")
@Transactional
public class AdminOrganizationsSVImpl implements IAdminOrganizationsSV {
	@Resource
	private AdminOrganizationsDAO adminOrganizationsDAO;

	@Override
	public void delete(Long id) throws Exception {

		if (null == id) {
			throw new XHZException(ErrorCode.ILLEGAL_REQUEST.ERROR_REQUEST);
		}
		Criteria criteria = new Criteria();
		criteria.addEqual(AdminOrganizations.COL_PARENT_ID, id, Criteria.AND);
		criteria.addEqual(AdminOrganizations.COL_STATUS, RecordState.STS_USE,
				Criteria.AND);
		criteria.limit(Constant.ZERO, Constant.ONE);

		List<AdminOrganizations> list = adminOrganizationsDAO
				.queryByCondition(criteria);

		if (CollectionUtils.isNotEmpty(list)) {
			throw new XHZException(ErrorCode.ORGANIZATION.HAS_CHILD);
		}

		adminOrganizationsDAO.delete(id);
	}

	@Override
	@Transactional(readOnly = true)
	public AdminOrganizations queryById(Long id) throws Exception {
		return adminOrganizationsDAO.queryById(id);
	}

	@Override
	public AdminOrganizations save(AdminOrganizations adminOrganizations)
			throws Exception {
		if (null == adminOrganizations || null != adminOrganizations.getOrgId()
				|| null == adminOrganizations.getParentId()
				|| StringUtils.isBlank(adminOrganizations.getParentCode())) {
			throw new XHZException(ErrorCode.ILLEGAL_REQUEST.ERROR_REQUEST);
		}
		String pOrgCode = adminOrganizations.getParentCode();
		Long pOrgId = adminOrganizations.getParentId();

		AdminOrganizations pOrg = adminOrganizationsDAO.queryById(pOrgId);
		/** 检查传过来的上级组织机构编号&组织机构代码是否存在 */
		if (null == pOrg || !pOrgCode.equals(pOrg.getOrgCode())) {
			throw new XHZException(ErrorCode.ORGANIZATION.PRAMS_ERROR);
		}
		/** 判断状态是否正常 */
		if (RecordState.STS_USE != pOrg.getStatus()) {
			throw new XHZException(ErrorCode.ORGANIZATION.STATUS_ERROR);
		}

		Criteria criteria = new Criteria();
		criteria.addEqual(AdminOrganizations.COL_PARENT_ID, pOrgId,
				Criteria.AND);
		criteria.addEqual(AdminOrganizations.COL_PARENT_CODE, pOrgCode,
				Criteria.AND);
		criteria.orderBy(AdminOrganizations.COL_ORG_CODE + " DESC");
		criteria.limit(Constant.ZERO, Constant.ONE);

		List<AdminOrganizations> list = adminOrganizationsDAO
				.queryByCondition(criteria);
		Integer orgCode = Constant.ORG_MIN_RECORD;
		/** 判断在上级组织机构下面是否已存在子组织机构 */
		if (CollectionUtils.isNotEmpty(list)) {
			AdminOrganizations currMacOrg = list.get(Constant.ZERO);
			String codeT = currMacOrg.getOrgCode().replaceFirst(pOrgCode, "");
			Integer intCode = Integer.valueOf(codeT);
			orgCode = intCode + 1;
			/** 判断组织机构是否超过了最大深度 */
			if (Constant.ORG_MAX_RECORD < orgCode) {
				throw new XHZException(ErrorCode.ORGANIZATION.MAX_ERROR);
			}
		}
		adminOrganizations.setOrgId(null);
		adminOrganizations.setOrgCode(pOrgCode
				+ String.format(Constant.ORG_TEMPLATE, orgCode));

		adminOrganizationsDAO.insert(adminOrganizations);

		return adminOrganizations;
	}

	@Override
	public void update(AdminOrganizations adminOrganizations) throws Exception {
		if (null == adminOrganizations || null == adminOrganizations.getOrgId()) {
			throw new XHZException(ErrorCode.ILLEGAL_REQUEST.ERROR_REQUEST);
		}

		adminOrganizations.setParentCode(null);
		adminOrganizations.setParentId(null);

		adminOrganizationsDAO.update(adminOrganizations);
	}

	@Override
	public void saveOrUpdate(AdminOrganizations adminOrganizations)
			throws Exception {
		if (adminOrganizations == null)
			return;
		if (StringUtils.isNotBlank("" + adminOrganizations.getOrgId())) {
			update(adminOrganizations);
		} else {
			save(adminOrganizations);
		}
	}

	@Override
	public void saveOrUpdate(List<AdminOrganizations> list) throws Exception {
		if (CollectionUtils.isNotEmpty(list)) {
			for (AdminOrganizations adminOrganizations : list) {
				saveOrUpdate(adminOrganizations);
			}
		}
	}

	@Override
	@Transactional(readOnly = true)
	public List<AdminOrganizations> queryByCondition(Criteria criteria)
			throws Exception {
		return adminOrganizationsDAO.queryByCondition(criteria);
	}

	@Override
	@Transactional(readOnly = true)
	public int queryCountByCondition(Criteria criteria) throws Exception {
		return adminOrganizationsDAO.queryCountByCondition(criteria);
	}

	@Override
	@Transactional(readOnly = true)
	public BootGridPage<AdminOrganizations> queryPage(Criteria criteria,
			BootGrid<AdminOrganizations> grid) throws Exception {

		// AdminOrganizations model = grid.getEntity();

		int totalCount = adminOrganizationsDAO.queryCountByCondition(criteria);

		if (Constant.ZERO < totalCount) {

			Map<String, String> sorts = grid.getSort();

			/** 设置排序规则 **/
			if (MapUtils.isNotEmpty(sorts)) {
				Set<String> keySets = sorts.keySet();
				String sort = "";
				for (String key : keySets) {
					sort += " , " + key + " " + sorts.get(key);
				}
				criteria.orderBy(sort.replaceFirst(",", ""));
			}
			if (grid.getCurrent() >= Constant.ZERO) {
				int start = (grid.getCurrent() - Constant.ONE)
						* grid.getRowCount();
				int size = grid.getRowCount();

				criteria.limit(start, size);
			}
			List<AdminOrganizations> list = adminOrganizationsDAO
					.queryByCondition(criteria);
			BootGridPage<AdminOrganizations> page = new BootGridPage<AdminOrganizations>(
					grid.getCurrent(), grid.getRowCount(), totalCount, list);

			return page;
		}
		return new BootGridPage<AdminOrganizations>(grid.getCurrent(),
				grid.getRowCount(), totalCount,
				new ArrayList<AdminOrganizations>());

	}

}
